/*
 * Copyright (C) 2007-2012 by XDEV Software, All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 3.0 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 
package xdev.db;


import java.io.PrintStream;


/**
 * A table of data representing a database result set, which is usually
 * generated by executing a statement that queries the database.
 * <p>
 * A Result object maintains a cursor pointing to its current row of data.
 * Initially the cursor is positioned before the first row. The {@link #next()}
 * method moves the cursor to the next row, and because it returns false when
 * there are no more rows in the Result object, it can be used in a while loop
 * to iterate through the result set.
 * <p>
 * The Result interface provides getter methods ({@link #getInt(int)},
 * {@link #getString(int)} , and so on) for retrieving column values from the
 * current row. Values can be retrieved using either the index number of the
 * column or the name of the column. In general, using the column index will be
 * more efficient. Columns are numbered from 0. For maximum portability, result
 * set columns within each row should be read in left-to-right order, and each
 * column should be read only once. For the getter methods, a driver attempts to
 * convert the underlying data to the Java type specified in the getter method
 * and returns a suitable Java value.
 * <p>
 * Column names used as input to getter methods are case insensitive. When a
 * getter method is called with a column name and several columns have the same
 * name, the value of the first matching column will be returned. The column
 * name option is designed to be used when column names are used in the SQL
 * query that generated the result set. For columns that are NOT explicitly
 * named in the query, it is best to use column numbers. If column names are
 * used, the programmer should take care to guarantee that they uniquely refer
 * to the intended columns, which can be assured with the SQL AS clause.
 * <p>
 * The number, types and properties of a Results object's column are provided by
 * the {@link ColumnMetaData} object returned by the {@link #getMetadata(int)}
 * method.
 * 
 * @author XDEV Software
 * 
 */
public abstract class Result
{
	private transient DBDataSource	dataSource;
	private Integer					maxRowCount;
	private transient QueryInfo		queryInfo;
	

	/**
	 * Sets the <code>dataSource</code> for this {@link Result}.
	 * 
	 * @param dataSource
	 *            the {@link DBDataSource} of this {@link Result}
	 */
	public void setDataSource(DBDataSource dataSource)
	{
		this.dataSource = dataSource;
	}
	

	/**
	 * Gets the {@link DBDataSource} of this {@link Result}.
	 * 
	 * @return the {@link DBDataSource} of this {@link Result}
	 */
	public DBDataSource getDataSource()
	{
		return dataSource;
	}
	

	/**
	 * Sets the <code>queryInfo</code> for this {@link Result}.
	 * 
	 * @param queryInfo
	 *            the {@link QueryInfo} of this {@link Result}
	 */
	public void setQueryInfo(QueryInfo queryInfo)
	{
		this.queryInfo = queryInfo;
	}
	

	/**
	 * Gets the {@link QueryInfo} of this {@link Result}.
	 * 
	 * @return the {@link QueryInfo} of this {@link Result}
	 */
	public QueryInfo getQueryInfo()
	{
		return queryInfo;
	}
	

	/**
	 * Sets the maxRowCount for this <code>Result</code> instance,
	 * <code>null</code> means not specified.
	 * 
	 * @param maxRowCount
	 */
	
	public void setMaxRowCount(Integer maxRowCount)
	{
		this.maxRowCount = maxRowCount;
	}
	

	/**
	 * Returns the <code>maxRowCount</code> for this {@link Result}.
	 * 
	 * @return the maxRowCount for this <code>Result</code> instance or
	 *         <tt>null</tt> if none has been specified.
	 */
	public Integer getMaxRowCount()
	{
		return maxRowCount;
	}
	

	/**
	 * Returns the number of columns.
	 * 
	 * @return the number of columns as <code>int</code> value.
	 */
	public abstract int getColumnCount();
	

	/**
	 * Returns the cached <code>ColumnMetadata</code> for the column with index
	 * <code>col</code>.
	 * <p>
	 * Note that <code>col</code> starts with 0 for the first column.
	 * <p>
	 * 
	 * @param col
	 *            the index of the column whose <code>ColumnMetadata</code>
	 *            shall be returned, starting at 0
	 * @return the cached <code>ColumnMetadata</code> of the column with index
	 *         <code>col</code>
	 */
	public abstract ColumnMetaData getMetadata(int col);
	

	/**
	 * 
	 * 
	 * 
	 * @return <code>true</code> if there is another row to be returned,
	 *         otherwise <code>false</code>.
	 * 
	 * @throws DBException
	 *             if any error occurred.
	 */
	public abstract boolean next() throws DBException;
	

	/**
	 * Skips over the specified count of rows.
	 * <p>
	 * The skip method may, for a variety of reasons, end up skipping over some
	 * smaller number of rows, possibly 0. This may be caused by reaching the
	 * end of the result.
	 * 
	 * @param count
	 *            the number of rows to skip
	 * @return the actual number of rows skipped
	 * @throws DBException
	 *             if any error occured
	 */
	public abstract int skip(int count) throws DBException;
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>Object</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a <code>java.lang.Object</code> holding the column value
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs.
	 */
	public abstract Object getObject(int col) throws DBException;
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>Object</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a <code>java.lang.Object</code> holding the column value
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs.
	 */
	public Object getObject(String colName) throws DBException
	{
		return getObject(getColumnIndex(colName));
	}
	

	/**
	 * Returns the index of the column with the specified name.
	 * 
	 * @param colName
	 *            as a {@link String}
	 * 
	 * @return the index for the specified column as int value
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs.
	 */
	public int getColumnIndex(String colName) throws DBException
	{
		int c = getColumnCount();
		for(int i = 0; i < c; i++)
		{
			if(getMetadata(i).getName().equalsIgnoreCase(colName))
			{
				return i;
			}
		}
		
		throw new DBException(dataSource,"Column '" + colName + "' not found");
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>String</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a {@link String} holding the column value
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs.
	 * 
	 * @see #getString(int, String)
	 */
	public String getString(int col) throws DBException
	{
		return getString(col,null);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>String</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @param defaultValue
	 *            the default <code>String</code>
	 * 
	 * @return a {@link String} holding the column value, if the column value is
	 *         <code>null</code> the <code>defaultValue</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs.
	 * 
	 * @see #getObject(int)
	 */
	public String getString(int col, String defaultValue) throws DBException
	{
		Object o = getObject(col);
		if(o == null)
		{
			return defaultValue;
		}
		
		return o.toString();
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>String</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a {@link String} holding the column value
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs.
	 */
	public String getString(String colName) throws DBException
	{
		return getString(getColumnIndex(colName));
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>String</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @param defaultValue
	 *            the default <code>String</code>
	 * 
	 * @return a {@link String} holding the column value, if the column value is
	 *         <code>null</code> the <code>defaultValue</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getString(int, String)
	 */
	public String getString(String colName, String defaultValue) throws DBException
	{
		return getString(getColumnIndex(colName),defaultValue);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>byte</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a <code>byte</code> holding the column value; If the column value
	 *         is <code>null</code>, <tt>0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getByte(int, byte)
	 */
	public byte getByte(int col) throws DBException
	{
		return getByte(col,(byte)0);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>byte</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @param defaultValue
	 *            the default <code>byte</code>
	 * 
	 * @return a <code>byte</code> holding the column value, if the column value
	 *         is <code>null</code> the <code>defaultValue</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getObject(int)
	 */
	public byte getByte(int col, byte defaultValue) throws DBException
	{
		Object o = getObject(col);
		if(o == null)
		{
			return defaultValue;
		}
		
		try
		{
			return ((Number)o).byteValue();
		}
		catch(ClassCastException cce)
		{
			throw new DBException(dataSource,cce);
		}
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>byte</code>.
	 * </p>
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a <code>byte</code> holding the column value; If the column value
	 *         is <code>null</code>, <tt>0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getByte(int)
	 */
	public byte getByte(String colName) throws DBException
	{
		return getByte(getColumnIndex(colName));
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>byte</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @param defaultValue
	 *            the default <code>byte</code>
	 * 
	 * @return a <code>byte</code> holding the column value, if the column value
	 *         is <code>null</code> the <code>defaultValue</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getByte(int, byte)
	 */
	public byte getByte(String colName, byte defaultValue) throws DBException
	{
		return getByte(getColumnIndex(colName),defaultValue);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>short</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a <code>short</code> holding the column value; If the column
	 *         value is <code>null</code>, <tt>0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getShort(int, short)
	 */
	public short getShort(int col) throws DBException
	{
		return getShort(col,(short)0);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>short</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @param defaultValue
	 *            the default <code>byte</code>
	 * 
	 * @return a <code>short</code> holding the column value, if the column
	 *         value is <code>null</code> the <code>defaultValue</code> is
	 *         returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getObject(int)
	 */
	public short getShort(int col, short defaultValue) throws DBException
	{
		Object o = getObject(col);
		if(o == null)
		{
			return defaultValue;
		}
		
		try
		{
			return ((Number)o).shortValue();
		}
		catch(ClassCastException cce)
		{
			throw new DBException(dataSource,cce);
		}
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>short</code>.
	 * </p>
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a <code>short</code> holding the column value; If the column
	 *         value is <code>null</code>, <tt>0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getShort(int)
	 */
	public short getShort(String colName) throws DBException
	{
		return getShort(getColumnIndex(colName));
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>short</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @param defaultValue
	 *            the default <code>short</code>
	 * 
	 * @return a <code>short</code> holding the column value, if the column
	 *         value is <code>null</code> the <code>defaultValue</code> is
	 *         returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getShort(int, short)
	 */
	public short getShort(String colName, short defaultValue) throws DBException
	{
		return getShort(getColumnIndex(colName),defaultValue);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>int</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a <code>int</code> holding the column value. If the column value
	 *         is <code>null</code>, <tt>0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getInt(int, int)
	 */
	public int getInt(int col) throws DBException
	{
		return getInt(col,0);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>int</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @param defaultValue
	 *            the default <code>int</code>
	 * 
	 * @return a <code>int</code> holding the column value, if the column value
	 *         is <code>null</code> the <code>defaultValue</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getObject(int)
	 */
	public int getInt(int col, int defaultValue) throws DBException
	{
		Object o = getObject(col);
		if(o == null)
		{
			return defaultValue;
		}
		
		try
		{
			return ((Number)o).intValue();
		}
		catch(ClassCastException cce)
		{
			throw new DBException(dataSource,cce);
		}
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>int</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a <code>int</code> holding the column value. If the column value
	 *         is <code>null</code>, <tt>0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getInt(int)
	 */
	public int getInt(String colName) throws DBException
	{
		return getInt(getColumnIndex(colName));
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>int</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @param defaultValue
	 *            the default <code>int</code>
	 * 
	 * @return a <code>int</code> holding the column value, if the column value
	 *         is <code>null</code> the <code>defaultValue</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getInt(int, int)
	 */
	public int getInt(String colName, int defaultValue) throws DBException
	{
		return getInt(getColumnIndex(colName),defaultValue);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>long</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a <code>long</code> holding the column value. If the column value
	 *         is <code>null</code>, <tt>0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getLong(int, long)
	 */
	public long getLong(int col) throws DBException
	{
		return getLong(col,0);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>long</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @param defaultValue
	 *            the default <code>long</code>
	 * 
	 * @return a <code>long</code> holding the column value, if the column value
	 *         is <code>null</code> the <code>defaultValue</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getObject(int)
	 */
	public long getLong(int col, long defaultValue) throws DBException
	{
		Object o = getObject(col);
		if(o == null)
		{
			return defaultValue;
		}
		
		try
		{
			return ((Number)o).longValue();
		}
		catch(ClassCastException cce)
		{
			throw new DBException(dataSource,cce);
		}
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>long</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a <code>long</code> holding the column value. If the column value
	 *         is <code>null</code>, <tt>0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getLong(int)
	 */
	public long getLong(String colName) throws DBException
	{
		return getLong(getColumnIndex(colName));
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>long</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @param defaultValue
	 *            the default <code>long</code>
	 * 
	 * @return a <code>long</code> holding the column value, if the column value
	 *         is <code>null</code> the <code>defaultValue</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getLong(int, long)
	 */
	public long getLong(String colName, long defaultValue) throws DBException
	{
		return getLong(getColumnIndex(colName),defaultValue);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>float</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a <code>float</code> holding the column value. If the column
	 *         value is <code>null</code>, <tt>0f</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getFloat(int, float)
	 */
	public float getFloat(int col) throws DBException
	{
		return getFloat(col,0f);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>float</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @param defaultValue
	 *            the default <code>float</code>
	 * 
	 * @return a <code>float</code> holding the column value, if the column
	 *         value is <code>null</code> the <code>defaultValue</code> is
	 *         returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getObject(int)
	 */
	public float getFloat(int col, float defaultValue) throws DBException
	{
		Object o = getObject(col);
		if(o == null)
		{
			return defaultValue;
		}
		
		try
		{
			return ((Number)o).floatValue();
		}
		catch(ClassCastException cce)
		{
			throw new DBException(dataSource,cce);
		}
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>float</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a <code>float</code> holding the column value. If the column
	 *         value is <code>null</code>, <tt>0f</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getFloat(int)
	 */
	public float getFloat(String colName) throws DBException
	{
		return getFloat(getColumnIndex(colName));
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>float</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @param defaultValue
	 *            the default <code>float</code>
	 * 
	 * @return a <code>float</code> holding the column value, if the column
	 *         value is <code>null</code> the <code>defaultValue</code> is
	 *         returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getFloat(int, float)
	 */
	public float getFloat(String colName, float defaultValue) throws DBException
	{
		return getFloat(getColumnIndex(colName),defaultValue);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>double</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a <code>double</code> holding the column value. If the column
	 *         value is <code>null</code>, <tt>0.0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getDouble(int, double)
	 */
	public double getDouble(int col) throws DBException
	{
		return getDouble(col,0.0);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>double</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @param defaultValue
	 *            the default <code>double</code>
	 * 
	 * @return a <code>double</code> holding the column value, if the column
	 *         value is <code>null</code> the <code>defaultValue</code> is
	 *         returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getObject(int)
	 */
	public double getDouble(int col, double defaultValue) throws DBException
	{
		Object o = getObject(col);
		if(o == null)
		{
			return defaultValue;
		}
		
		try
		{
			return ((Number)o).doubleValue();
		}
		catch(ClassCastException cce)
		{
			throw new DBException(dataSource,cce);
		}
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>double</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a <code>double</code> holding the column value. If the column
	 *         value is <code>null</code>, <tt>0.0</tt> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 */
	public double getDouble(String colName) throws DBException
	{
		return getDouble(getColumnIndex(colName));
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>double</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @param defaultValue
	 *            the default <code>double</code>
	 * 
	 * @return a <code>double</code> holding the column value, if the column
	 *         value is <code>null</code> the <code>defaultValue</code> is
	 *         returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getDouble(int, double)
	 */
	public double getDouble(String colName, double defaultValue) throws DBException
	{
		return getDouble(getColumnIndex(colName),defaultValue);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>boolean</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @return a <code>boolean</code> holding the column value. If the column
	 *         value is <code>null</code>, <code>false</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getBoolean(int, boolean)
	 */
	public boolean getBoolean(int col) throws DBException
	{
		return getBoolean(col,false);
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>boolean</code>.
	 * </p>
	 * 
	 * @param col
	 *            the index of the column
	 * 
	 * @param defaultValue
	 *            the default <code>boolean</code>
	 * 
	 * @return a <code>boolean</code> holding the column value, if the column
	 *         value is <code>null</code> the <code>defaultValue</code> is
	 *         returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getObject(int)
	 */
	public boolean getBoolean(int col, boolean defaultValue) throws DBException
	{
		Object o = getObject(col);
		if(o == null)
		{
			return defaultValue;
		}
		
		try
		{
			return (Boolean)o;
		}
		catch(ClassCastException cce)
		{
			throw new DBException(dataSource,cce);
		}
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>boolean</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @return a <code>boolean</code> holding the column value. If the column
	 *         value is <code>null</code>, <code>false</code> is returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getBoolean(int)
	 */
	public boolean getBoolean(String colName) throws DBException
	{
		return getBoolean(getColumnIndex(colName));
	}
	

	/**
	 * <p>
	 * Gets the value of the designated column in the current row of this
	 * {@link Result} object as an <code>boolean</code>.
	 * </p>
	 * 
	 * 
	 * @param colName
	 *            the name of the column
	 * 
	 * @param defaultValue
	 *            the default <code>boolean</code>
	 * 
	 * @return a <code>boolean</code> holding the column value, if the column
	 *         value is <code>null</code> the <code>defaultValue</code> is
	 *         returned.
	 * 
	 * @throws DBException
	 *             if the columnIndex is not valid; if a database access error
	 *             occurs or the value can not be cast.
	 * 
	 * @see #getColumnIndex(String)
	 * @see #getBoolean(int, boolean)
	 */
	public boolean getBoolean(String colName, boolean defaultValue) throws DBException
	{
		return getBoolean(getColumnIndex(colName),defaultValue);
	}
	

	/**
	 * Closes this {@link Result} and releases all used resources.
	 * 
	 * @throws DBException
	 *             if a database access error occurs.
	 */
	public abstract void close() throws DBException;
	

	/**
	 * Prints the contents of this result to {@link System#out}.
	 * 
	 * @since 3.1
	 */
	public void dump() throws DBException
	{
		dump(System.out);
	}
	

	/**
	 * Prints the contents of this result to <code>out</code>.
	 * 
	 * @param out
	 *            the stream to print to
	 * 
	 * @since 3.1
	 */
	public void dump(PrintStream out) throws DBException
	{
		int columnCount = getColumnCount();
		for(int col = 0; col < columnCount; col++)
		{
			if(col > 0)
			{
				out.print("\t");
			}
			ColumnMetaData meta = getMetadata(col);
			out.print(meta.getName() + "(" + meta.getType().name() + ")");
		}
		out.println();
		out.println();
		while(next())
		{
			for(int col = 0; col < columnCount; col++)
			{
				if(col > 0)
				{
					out.print("\t");
				}
				out.print(String.valueOf(getObject(col)));
			}
			out.println();
		}
	}
}
